home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / ncurses-5.3.lha / ncurses-5.3 / tack / fun.c < prev    next >
C/C++ Source or Header  |  2002-10-24  |  20KB  |  913 lines

  1. /*
  2. ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
  3. ** 
  4. ** This file is part of TACK.
  5. ** 
  6. ** TACK is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2, or (at your option)
  9. ** any later version.
  10. ** 
  11. ** TACK is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** 
  16. ** You should have received a copy of the GNU General Public License
  17. ** along with TACK; see the file COPYING.  If not, write to
  18. ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. ** Boston, MA 02111-1307, USA.
  20. */
  21.  
  22. #include <tack.h>
  23.  
  24. MODULE_ID("$Id: fun.c,v 1.3 2000/03/04 20:29:21 tom Exp $")
  25.  
  26. /*
  27.  * Test the function keys on the terminal.  The code for echo tests
  28.  * lives here too.
  29.  */
  30.  
  31. static void funkey_keys(struct test_list *, int *, int *);
  32. static void funkey_meta(struct test_list *, int *, int *);
  33. static void funkey_label(struct test_list *, int *, int *);
  34. static void funkey_prog(struct test_list *, int *, int *);
  35. static void funkey_local(struct test_list *, int *, int *);
  36.  
  37. struct test_list funkey_test_list[] = {
  38.     {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
  39.     {MENU_CLEAR + FLAG_FUNCTION_KEY, 0, 0, 0, "f) show a list of function keys", show_report, 0},
  40.     {MENU_NEXT | MENU_CLEAR, 0, "smkx) (rmkx", 0,
  41.         "k) test function keys", funkey_keys, 0},
  42.     {MENU_NEXT, 10, "km", "smm rmm", 0, funkey_meta, 0},
  43.     {MENU_NEXT, 8, "nlab) (smln) (pln) (rmln", "lw lh", 0, funkey_label, 0},
  44.     {MENU_NEXT, 2, "pfx", 0, 0, funkey_prog, 0},
  45.     {MENU_NEXT, 2, "pfloc", 0, 0, funkey_local, 0},
  46.     {MENU_LAST, 0, 0, 0, 0, 0, 0}
  47. };
  48.  
  49. static void printer_on(struct test_list *, int *, int *);
  50. static void printer_mc0(struct test_list *, int *, int *);
  51.  
  52. struct test_list printer_test_list[] = {
  53.     {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
  54.     {MENU_NEXT | MENU_CLEAR, 0, "mc4) (mc5) (mc5i", 0, 0, printer_on, 0},
  55.     {MENU_NEXT | MENU_CLEAR, 0, "mc0", 0, 0, printer_mc0, 0},
  56.     {MENU_LAST, 0, 0, 0, 0, 0, 0}
  57. };
  58.  
  59. #define MAX_STRINGS STRCOUNT
  60.  
  61. /* scan code externals */
  62. extern int scan_max;        /* length of longest scan code */
  63. extern char **scan_up, **scan_down, **scan_name;
  64. extern int *scan_tested, *scan_length;
  65.  
  66. /* local definitions */
  67. static const char *fk_name[MAX_STRINGS];
  68. static char *fkval[MAX_STRINGS];
  69. static char *fk_label[MAX_STRINGS];    /* function key labels (if any) */
  70. static int fk_tested[MAX_STRINGS];
  71. static int fkmax = 1;        /* length of longest key */
  72. static int got_labels = 0;    /* true if we have some labels */
  73. static int key_count = 0;
  74. static int end_state;
  75.  
  76. /* unknown function keys */
  77. #define MAX_FK_UNK 50
  78. static char *fk_unknown[MAX_FK_UNK];
  79. static int fk_length[MAX_FK_UNK];
  80. static int funk;
  81.  
  82. /*
  83. **    keys_tested(first-time, show-help, hex-output)
  84. **
  85. **    Display a list of the keys not tested.
  86. */
  87. static void
  88. keys_tested(
  89.     int first_time,
  90.     int show_help,
  91.     int hex_output)
  92. {
  93.     int i, l;
  94.     char outbuf[256];
  95.  
  96.     put_clear();
  97.     tty_set();
  98.     flush_input();
  99.     if (got_labels) {
  100.         putln("Function key labels:");
  101.         for (i = 0; i < key_count; ++i) {
  102.             if (fk_label[i]) {
  103.                 sprintf(outbuf, "%s %s",
  104.                     fk_name[i] ? fk_name[i] : "??", fk_label[i]);
  105.                 put_columns(outbuf, strlen(outbuf), 16);
  106.             }
  107.         }
  108.         put_newlines(2);
  109.     }
  110.     if (funk) {
  111.         putln("The following keys are not defined:");
  112.         for (i = 0; i < funk; ++i) {
  113.             put_columns(fk_unknown[i], fk_length[i], 16);
  114.         }
  115.         put_mode(exit_attribute_mode);
  116.         put_newlines(2);
  117.     }
  118.     if (first_time) {
  119.         putln("The following keys are defined:");
  120.     } else {
  121.         putln("The following keys have not been tested:");
  122.     }
  123.     if (scan_mode) {
  124.         for (i = 0; scan_down[i]; i++) {
  125.             if (!scan_tested[i]) {
  126.                 if (hex_output) {
  127.                     strcpy(outbuf, hex_expand_to(scan_down[i], 3));
  128.                 } else {
  129.                     strcpy(outbuf, expand(scan_down[i]));
  130.                 }
  131.                 l = expand_chars;
  132.                 if (hex_output) {
  133.                     strcat(outbuf, hex_expand_to(scan_up[i], 3));
  134.                 } else {
  135.                     strcat(outbuf, expand(scan_up[i]));
  136.                 }
  137.                 expand_chars += l;
  138.                 l = strlen(scan_name[i]);
  139.                 if (((char_count + 16) & ~15) +
  140.                     ((expand_chars + 7) & ~7) + l >= columns) {
  141.                     put_crlf();
  142.                 } else
  143.                 if (char_count + 24 > columns) {
  144.                     put_crlf();
  145.                 } else if (char_count) {
  146.                     putchp(' ');
  147.                 }
  148.                 put_columns(outbuf, expand_chars, 16);
  149.                 put_columns(scan_name[i], l, 8);
  150.             }
  151.         }
  152.     } else {
  153.         for (i = 0; i < key_count; i++) {
  154.             if (!fk_tested[i]) {
  155.                 if (hex_output) {
  156.                     strcpy(outbuf, hex_expand_to(fkval[i], 3));
  157.                 } else {
  158.                     strcpy(outbuf, expand(fkval[i]));
  159.                 }
  160.                 l = strlen(fk_name[i]);
  161.                 if (((char_count + 16) & ~15) +
  162.                     ((expand_chars + 7) & ~7) + l >= columns) {
  163.                     put_crlf();
  164.                 } else
  165.                 if (char_count + 24 > columns) {
  166.                     put_crlf();
  167.                 } else
  168.                 if (char_count) {
  169.                     putchp(' ');
  170.                 }
  171.                 put_columns(outbuf, expand_chars, 16);
  172.                 put_columns(fk_name[i], l, 8);
  173.             }
  174.         }
  175.     }
  176.     put_newlines(2);
  177.     if (show_help) {
  178.         ptextln("Hit any function key.  Type 'end' to quit.  Type ? to update the display.");
  179.         put_crlf();
  180.     }
  181. }
  182.  
  183. /*
  184. **    enter_key(name, value, label)
  185. **
  186. **    Enter a function key into the data base
  187. */
  188. void
  189. enter_key(
  190.     const char *name,
  191.     char *value,
  192.     char *lab)
  193. {
  194.     int j;
  195.  
  196.     if (value) {
  197.         j = strlen(value);
  198.         fkmax = fkmax > j ? fkmax : j;
  199.         /* do not permit duplicates */
  200.         for (j = 0; j < key_count; j++) {
  201.             if (!strcmp(fk_name[j], name)) {
  202.                 return;
  203.             }
  204.         }
  205.         fkval[key_count] = value;
  206.         fk_tested[key_count] = 0;
  207.         fk_label[key_count] = lab;
  208.         fk_name[key_count++] = name;
  209.         if (lab) {
  210.             got_labels = TRUE;
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216. static void
  217. fresh_line(void)
  218. {                /* clear the line for a new function key line */
  219.     if (over_strike) {
  220.         put_crlf();
  221.     } else {
  222.         put_cr();
  223.         if (clr_eol) {
  224.             tc_putp(clr_eol);
  225.         } else {
  226.             put_str("                    \r");
  227.         }
  228.     }
  229. }
  230.  
  231.  
  232. static int
  233. end_funky(int ch)
  234. {                /* return true if this is the end */
  235.     switch (ch) {
  236.     case 'e':
  237.     case 'E':
  238.         end_state = 'e';
  239.         break;
  240.     case 'n':
  241.     case 'N':
  242.         if (end_state == 'e') {
  243.             end_state = 'n';
  244.         } else {
  245.             end_state = 0;
  246.         }
  247.         break;
  248.     case 'd':
  249.     case 'D':
  250.         if (end_state == 'n') {
  251.             end_state = 'd';
  252.         } else {
  253.             end_state = 0;
  254.         }
  255.         break;
  256.     case 'l':
  257.     case 'L':
  258.         if (end_state == 'l') {
  259.             end_state = '?';
  260.         } else {
  261.             end_state = 'l';
  262.         }
  263.         break;
  264.     default:
  265.         end_state = 0;
  266.         break;
  267.     }
  268.     return end_state == 'd';
  269. }
  270.  
  271.  
  272. static int
  273. found_match(char *s, int hx, int cc)
  274. {                /* return true if this string is a match */
  275.     int j, f;
  276.     char outbuf[256];
  277.  
  278.     if (!*s) {
  279.         return 0;
  280.     }
  281.     if (scan_mode) {
  282.         for (j = f = 0; scan_down[j]; j++) {
  283.             if (scan_length[j] == 0) {
  284.                 continue;
  285.             }
  286.             if (!strncmp(s, scan_down[j], scan_length[j])) {
  287.                 if (!f) {    /* first match */
  288.                     put_cr();
  289.                     if (hx) {
  290.                         put_str(hex_expand_to(s, 10));
  291.                     } else {
  292.                         put_str(expand_to(s, 10));
  293.                     }
  294.                     f = 1;
  295.                 }
  296.                 (void) end_funky(scan_name[j][0]);
  297.                 put_str(" ");
  298.                 put_str(scan_name[j]);
  299.                 scan_tested[j] = 1;
  300.                 s += scan_length[j];
  301.                 if (strncmp(s, scan_up[j], scan_length[j])) {
  302.                     put_str(" scan down");
  303.                 } else {
  304.                     s += scan_length[j];
  305.                 }
  306.                 if (!*s) {
  307.                     break;
  308.                 }
  309.                 j = -1;
  310.             }
  311.             if (!strncmp(s, scan_up[j], scan_length[j])) {
  312.                 if (!f) {    /* first match */
  313.                     put_cr();
  314.                     if (hx) {
  315.                         put_str(hex_expand_to(s, 10));
  316.                     } else {
  317.                         put_str(expand_to(s, 10));
  318.                     }
  319.                     f = 1;
  320.                 }
  321.                 put_str(" ");
  322.                 put_str(scan_name[j]);
  323.                 put_str(" scan up");
  324.                 s += scan_length[j];
  325.                 if (!*s) {
  326.                     break;
  327.                 }
  328.                 j = -1;
  329.             }
  330.         }
  331.     } else {
  332.         for (j = f = 0; j < key_count; j++) {
  333.             if (!strcmp(s, fkval[j])) {
  334.                 if (!f) {    /* first match */
  335.                     put_cr();
  336.                     if (hx) {
  337.                         put_str(hex_expand_to(s, 10));
  338.                     } else {
  339.                         put_str(expand_to(s, 10));
  340.                     }
  341.                     f = 1;
  342.                 }
  343.                 sprintf(outbuf, " (%s)", fk_name[j]);
  344.                 put_str(outbuf);
  345.                 if (fk_label[j]) {
  346.                     sprintf(outbuf, " <%s>", fk_label[j]);
  347.                     put_str(outbuf);
  348.                 }
  349.                 fk_tested[j] = 1;
  350.             }
  351.         }
  352.     }
  353.     if (end_state == '?') {
  354.         keys_tested(0, 1, hx);
  355.         tty_raw(cc, char_mask);
  356.         end_state = 0;
  357.     }
  358.     return f;
  359. }
  360.  
  361.  
  362. static int
  363. found_exit(char *keybuf, int hx, int cc)
  364. {                /* return true if the user wants to exit */
  365.     int j, k;
  366.     char *s;
  367.  
  368.  
  369.     if (scan_mode) {
  370.         if (*keybuf == '\0') {
  371.             return TRUE;
  372.         }
  373.     } else {
  374.         /* break is a special case */
  375.         if (*keybuf == '\0') {
  376.             fresh_line();
  377.             tty_set();
  378.             ptext("Hit X to exit: ");
  379.             if (wait_here() == 'X') {
  380.                 return TRUE;
  381.             }
  382.             keys_tested(0, 1, hx);
  383.             tty_raw(cc, char_mask);
  384.             return FALSE;
  385.         }
  386.         /* is this the end? */
  387.         for (k = 0; (j = (keybuf[k] & STRIP_PARITY)); k++) {
  388.             if (end_funky(j)) {
  389.                 return TRUE;
  390.             }
  391.         }
  392.  
  393.         j = TRUE;    /* does he need an updated list? */
  394.         for (k = 0; keybuf[k]; k++) {
  395.             j &= (keybuf[k] & STRIP_PARITY) == '?';
  396.         }
  397.         if (j || end_state == '?') {
  398.             keys_tested(0, 1, hx);
  399.             tty_raw(cc, char_mask);
  400.             end_state = 0;
  401.             return FALSE;
  402.         }
  403.     }
  404.  
  405.     put_cr();
  406.     if (hx) {
  407.         s = hex_expand_to(keybuf, 10);
  408.     } else {
  409.         s = expand_to(keybuf, 10);
  410.     }
  411.     sprintf(temp, "%s Unknown", s);
  412.     put_str(temp);
  413.     for (j = 0; j < MAX_FK_UNK; j++) {
  414.         if (j == funk) {
  415.             fk_length[funk] = expand_chars;
  416.             if ((fk_unknown[funk] = (char *)malloc(strlen(s) + 1))) {
  417.                 strcpy(fk_unknown[funk++], s);
  418.             }
  419.             break;
  420.         }
  421.         if (fk_length[j] == expand_chars) {
  422.             if (!strcmp(fk_unknown[j], s)) {
  423.                 break;
  424.             }
  425.         }
  426.     }
  427.     return FALSE;
  428. }
  429.  
  430. /*
  431. **    funkey_keys(test_list, status, ch)
  432. **
  433. **    Test function keys
  434. */
  435. static void
  436. funkey_keys(
  437.     struct test_list *t,
  438.     int *state,
  439.     int *ch)
  440. {
  441.     char keybuf[256];
  442.  
  443.     if (keypad_xmit) {
  444.         tc_putp(keypad_xmit);
  445.     }
  446.     keys_tested(1, 1, hex_out);    /* also clears screen */
  447.     keybuf[0] = '\0';
  448.     end_state = 0;
  449.     if (scan_mode) {
  450.         fkmax = scan_max;
  451.     }
  452.     tty_raw(0, char_mask);
  453.     while (end_state != 'd') {
  454.         read_key(keybuf, sizeof(keybuf));
  455.         fresh_line();
  456.         if (found_match(keybuf, hex_out, 0)) {
  457.             continue;
  458.         }
  459.         if (found_exit(keybuf, hex_out, 0)) {
  460.             break;
  461.         }
  462.     }
  463.     if (keypad_local) {
  464.         tc_putp(keypad_local);
  465.     }
  466.     keys_tested(0, 0, hex_out);
  467.     ptext("Function key test ");
  468.     generic_done_message(t, state, ch);
  469. }
  470.  
  471. int
  472. tty_meta_prep(void)
  473. {                /* print a warning before the meta key test */
  474.     if (not_a_tty) {
  475.         return 0;
  476.     }
  477.     if (initial_stty_query(TTY_8_BIT)) {
  478.         return 0;
  479.     }
  480.     ptext("The meta key test must be run with the");
  481.     ptext(" terminal set for 8 data bits.  Two stop bits");
  482.     ptext(" may also be needed for correct display.  I will");
  483.     ptext(" transmit 8 bit data but if the terminal is set for");
  484.     ptextln(" 7 bit data, garbage may appear on the screen.");
  485.     return 1;
  486. }
  487.  
  488. /*
  489. **    funkey_meta(test_list, status, ch)
  490. **
  491. **    Test meta key (km) (smm) (rmm)
  492. */
  493. static void
  494. funkey_meta(
  495.     struct test_list *t,
  496.     int *state,
  497.     int *ch)
  498. {
  499.     int i, j, k, len;
  500.     char outbuf[256];
  501.  
  502.     if (has_meta_key) {
  503.         put_crlf();
  504.         if (char_mask != ALLOW_PARITY) {
  505.             if (tty_meta_prep()) {
  506.                 ptext("\nHit any key to continue > ");
  507.                 (void) wait_here();
  508.                 put_crlf();
  509.             }
  510.         }
  511.         ptext("Begin meta key test. (km) (smm) (rmm)  Hit any key");
  512.         ptext(" with the meta key.  The character will be");
  513.         ptext(" displayed in hex.  If the meta key is working");
  514.         ptext(" then the most significant bit will be set.  Type");
  515.         ptextln(" 'end' to exit.");
  516.         tty_raw(1, ALLOW_PARITY);
  517.         tc_putp(meta_on);
  518.  
  519.         for (i = j = k = len = 0; i != 'e' || j != 'n' || k != 'd';) {
  520.             i = j;
  521.             j = k;
  522.             k = getchp(ALLOW_PARITY);
  523.             if (k == EOF) {
  524.                 break;
  525.             }
  526.             if ((len += 3) >= columns) {
  527.                 put_crlf();
  528.                 len = 3;
  529.             }
  530.             sprintf(outbuf, "%02X ", k);
  531.             put_str(outbuf);
  532.             k &= STRIP_PARITY;
  533.         }
  534.         tc_putp(meta_off);
  535.         put_crlf();
  536.         tty_set();
  537.         put_crlf();
  538.     } else {
  539.         ptext("(km) Has-meta-key is not set.  ");
  540.     }
  541.     generic_done_message(t, state, ch);
  542. }
  543.  
  544. /*
  545. **    funkey_label(test_list, status, ch)
  546. **
  547. **    Test labels (nlab) (smln) (pln) (rmln) (lw) (lh)
  548. */
  549. static void
  550. funkey_label(
  551.     struct test_list *t,
  552.     int *state,
  553.     int *ch)
  554. {
  555.     int i;
  556.     char outbuf[256];
  557.  
  558.     if (num_labels == -1) {
  559.         ptextln("Your terminal has no labels. (nlab)");
  560.     } else {
  561.         sprintf(temp, "Your terminal has %d labels (nlab) that are %d characters wide (lw) and %d lines high (lh)",
  562.             num_labels, label_width, label_height);
  563.         ptext(temp);
  564.         ptextln(" Testing (smln) (pln) (rmln)");
  565.         if (label_on) {
  566.             tc_putp(label_on);
  567.         }
  568.         if (label_width <= 0) {
  569.             label_width = sizeof(outbuf) - 1;
  570.         }
  571.         for (i = 1; i <= num_labels; i++) {
  572.             sprintf(outbuf, "L%d..............................", i);
  573.             outbuf[label_width] = '\0';
  574.             tc_putp(tparm(plab_norm, i, outbuf));
  575.         }
  576.         if (label_off) {
  577.             ptext("Hit any key to remove the labels: ");
  578.             (void) wait_here();
  579.             tc_putp(label_off);
  580.         }
  581.     }
  582.     generic_done_message(t, state, ch);
  583. }
  584.  
  585. /*
  586. **    funkey_prog(test_list, status, ch)
  587. **
  588. **    Test program function keys (pfx)
  589. */
  590. static void
  591. funkey_prog(
  592.     struct test_list *t,
  593.     int *state,
  594.     int *ch)
  595. {
  596.     int i, fk;
  597.     char mm[256];
  598.  
  599.     fk = 1;    /* use function key 1 for now */
  600.     if (pkey_xmit) {
  601.         /* test program function key */
  602.         sprintf(temp,
  603.             "(pfx) Set function key %d to transmit abc\\n", fk);
  604.         ptextln(temp);
  605.         tc_putp(tparm(pkey_xmit, fk, "abc\n"));
  606.         sprintf(temp, "Hit function key %d\n", fk);
  607.         ptextln(temp);
  608.         for (i = 0; i < 4; ++i)
  609.             mm[i] = getchp(STRIP_PARITY);
  610.         mm[i] = '\0';
  611.         put_crlf();
  612.         if (mm[0] != 'a' || mm[1] != 'b' || mm[2] != 'c') {
  613.             sprintf(temp, "Error string received was: %s", expand(mm));
  614.             ptextln(temp);
  615.         } else {
  616.             putln("Thank you\n");
  617.         }
  618.         flush_input();
  619.         if (key_f1) {
  620.             tc_putp(tparm(pkey_xmit, fk, key_f1));
  621.         }
  622.     } else {
  623.         ptextln("Function key transmit (pfx), not present.");
  624.     }
  625.     generic_done_message(t, state, ch);
  626. }
  627.  
  628. /*
  629. **    funkey_local(test_list, status, ch)
  630. **
  631. **    Test program local function keys (pfloc)
  632. */
  633. static void
  634. funkey_local(
  635.     struct test_list *t,
  636.     int *state,
  637.     int *ch)
  638. {
  639.     int fk;
  640.  
  641.     fk = 1;
  642.     if (pkey_local) {
  643.         /* test local function key */
  644.         sprintf(temp,
  645.             "(pfloc) Set function key %d to execute a clear and print \"Done!\"", fk);
  646.         ptextln(temp);
  647.         sprintf(temp, "%sDone!", liberated(clear_screen));
  648.         tc_putp(tparm(pkey_local, fk, temp));
  649.         sprintf(temp, "Hit function key %d.  Then hit return.", fk);
  650.         ptextln(temp);
  651.         (void) wait_here();
  652.         flush_input();
  653.         if (key_f1 && pkey_xmit) {
  654.             tc_putp(tparm(pkey_xmit, fk, key_f1));
  655.         }
  656.     } else {
  657.         ptextln("Function key execute local (pfloc), not present.");
  658.     }
  659.  
  660.     generic_done_message(t, state, ch);
  661. }
  662.  
  663. /*
  664. **    printer_on(test_list, status, ch)
  665. **
  666. **    Test printer on/off (mc4) (mc5) (mc5i)
  667. */
  668. static void
  669. printer_on(
  670.     struct test_list *t,
  671.     int *state,
  672.     int *ch)
  673. {
  674.     if (!prtr_on || !prtr_off) {
  675.         ptextln("Printer on/off missing. (mc5) (mc4)");
  676.     } else if (prtr_silent) {
  677.         ptextln("Your printer is silent. (mc5i) is set.");
  678.         tc_putp(prtr_on);
  679.         ptextln("This line should be on the printer but not your screen. (mc5)");
  680.         tc_putp(prtr_off);
  681.         ptextln("This line should be only on the screen. (mc4)");
  682.     } else {
  683.         ptextln("Your printer is not silent. (mc5i) is reset.");
  684.         tc_putp(prtr_on);
  685.         ptextln("This line should be on the printer and the screen. (mc5)");
  686.         tc_putp(prtr_off);
  687.         ptextln("This line should only be on the screen. (mc4)");
  688.     }
  689.     generic_done_message(t, state, ch);
  690. }
  691.  
  692. /*
  693. **    printer_mc0(test_list, status, ch)
  694. **
  695. **    Test screen print (mc0)
  696. */
  697. static void
  698. printer_mc0(
  699.     struct test_list *t,
  700.     int *state,
  701.     int *ch)
  702. {
  703.     if (print_screen) {
  704.         ptext("I am going to send the contents of the screen to");
  705.         ptext(" the printer, then wait for a keystroke from you.");
  706.         ptext("  All of the text that appears on the screen");
  707.         ptextln(" should be printed. (mc0)");
  708.         tc_putp(print_screen);
  709.     } else {
  710.         ptext("(mc0) Print-screen is not present.  ");
  711.     }
  712.     generic_done_message(t, state, ch);
  713. }
  714.  
  715.  
  716. static void
  717. line_pattern(void)
  718. {                /* put up a pattern that will help count the
  719.                    number of lines */
  720.     int i, j;
  721.  
  722.     put_clear();
  723.     if (over_strike) {
  724.         for (i = 0; i < 100; i++) {
  725.             if (i) {
  726.                 put_crlf();
  727.             }
  728.             for (j = i / 10; j; j--) {
  729.                 put_this(' ');
  730.             }
  731.             put_this('0' + ((i + 1) % 10));
  732.         }
  733.     } else    /* I assume it will scroll */ {
  734.         for (i = 100; i; i--) {
  735.             sprintf(temp, "\r\n%d", i);
  736.             put_str(temp);
  737.         }
  738.     }
  739. }
  740.  
  741.  
  742. static void
  743. column_pattern(void)
  744. {                /* put up a pattern that will help count the
  745.                    number of columns */
  746.     int i, j;
  747.  
  748.     put_clear();
  749.     for (i = 0; i < 20; i++) {
  750.         for (j = 1; j < 10; j++) {
  751.             put_this('0' + j);
  752.         }
  753.         put_this('.');
  754.     }
  755. }
  756.  
  757. /*
  758. **    report_help()
  759. **
  760. **    Print the help text for the echo tests
  761. */
  762. static void
  763. report_help(int crx)
  764. {
  765.     ptextln("The following commands may also be entered:");
  766.     ptextln(" clear   clear screen.");
  767.     ptextln(" columns print a test pattern to help count screen width.");
  768.     ptextln(" lines   print a test pattern to help count screen length.");
  769.     ptextln(" end     exit.");
  770.     ptextln(" echo    redisplay last report.");
  771.     if (crx) {
  772.         ptextln(" hex     redisplay last report in hex.");
  773.     } else {
  774.         ptextln(" hex     toggle hex display mode.");
  775.     }
  776.     ptextln(" help    display this list.");
  777.     ptextln(" high    toggle forced high bit (0x80).");
  778.     ptextln(" scan    toggle scan mode.");
  779.     ptextln(" one     echo one character after <cr> or <lf> as is. (report mode)");
  780.     ptextln(" two     echo two characters after <cr> or <lf> as is.");
  781.     ptextln(" all     echo all characters after <cr> or <lf> as is. (echo mode)");
  782. }
  783.  
  784. /*
  785. **    tools_report(testlist, state, ch)
  786. **
  787. **    Run the echo tool and report tool
  788. */
  789. void
  790. tools_report(
  791.     struct test_list *t,
  792.     int *state GCC_UNUSED,
  793.     int *pch GCC_UNUSED)
  794. {
  795.     int i, j, ch, crp, crx, high_bit, save_scan_mode, hex_display;
  796.     char buf[1024];
  797.     char txt[8];
  798.  
  799.     hex_display = hex_out;
  800.     put_clear();
  801.     if ((crx = (t->flags & 255)) == 1) {
  802.         ptext("Characters after a CR or LF will be echoed as");
  803.         ptextln(" is.  All other characters will be expanded.");
  804.         report_help(crx);
  805.     } else {    /* echo test */
  806.         ptextln("Begin echo test.");
  807.         report_help(crx);
  808.     }
  809.     txt[sizeof(txt) - 1] = '\0';
  810.     save_scan_mode = scan_mode;
  811.     tty_raw(1, char_mask);
  812.     for (i = crp = high_bit = 0;;) {
  813.         ch = getchp(char_mask);
  814.         if (ch == EOF) {
  815.             break;
  816.         }
  817.         if (i >= (int) sizeof(buf) - 1) {
  818.             i = 0;
  819.         }
  820.         buf[i++] = ch;
  821.         buf[i] = '\0';
  822.         for (j = 0; j < (int) sizeof(txt) - 1; j++) {
  823.             txt[j] = txt[j + 1];
  824.         }
  825.         txt[sizeof(txt) - 1] = ch & STRIP_PARITY;
  826.         if (crx == 0) {    /* echo test */
  827.             if (hex_display) {
  828.                 ptext(hex_expand_to(&buf[i - 1], 3));
  829.             } else {
  830.                 tc_putch(ch | high_bit);
  831.             }
  832.         } else /* status report test */
  833.         if (ch == '\n' || ch == '\r') {
  834.             put_crlf();
  835.             crp = 0;
  836.         } else if (crp++ < crx) {
  837.             tc_putch(ch | high_bit);
  838.         } else {
  839.             put_str(expand(&buf[i - 1]));
  840.         }
  841.         if (!strncmp(&txt[sizeof(txt) - 7], "columns", 7)) {
  842.             column_pattern();
  843.             buf[i = 0] = '\0';
  844.             crp = 0;
  845.         }
  846.         if (!strncmp(&txt[sizeof(txt) - 5], "lines", 5)) {
  847.             line_pattern();
  848.             buf[i = 0] = '\0';
  849.             crp = 0;
  850.         }
  851.         if (!strncmp(&txt[sizeof(txt) - 5], "clear", 5)) {
  852.             put_clear();
  853.             buf[i = 0] = '\0';
  854.             crp = 0;
  855.         }
  856.         if (!strncmp(&txt[sizeof(txt) - 4], "high", 4)) {
  857.             high_bit ^= 0x80;
  858.             if (high_bit) {
  859.                 ptextln("\nParity bit set");
  860.             } else {
  861.                 ptextln("\nParity bit reset");
  862.             }
  863.         }
  864.         if (!strncmp(&txt[sizeof(txt) - 4], "help", 4)) {
  865.             put_crlf();
  866.             report_help(crx);
  867.         }
  868.         if (!strncmp(&txt[sizeof(txt) - 4], "echo", 4)) {
  869.             /* display the last status report */
  870.             /* clear bypass condition on Tek terminals */
  871.             put_crlf();
  872.             if (i >= 4) {
  873.                 buf[i -= 4] = '\0';
  874.             }
  875.             put_str(expand(buf));
  876.         }
  877.         if (save_scan_mode &&
  878.             !strncmp(&txt[sizeof(txt) - 4], "scan", 4)) {
  879.             /* toggle scan mode */
  880.             scan_mode = !scan_mode;
  881.         }
  882.         if (!strncmp(&txt[sizeof(txt) - 3], "end", 3))
  883.             break;
  884.         if (!strncmp(&txt[sizeof(txt) - 3], "hex", 3)) {
  885.             if (crx) {
  886.                 /* display the last status report in hex */
  887.                 /* clear bypass condition on Tek terminals */
  888.                 put_crlf();
  889.                 if (i >= 3) {
  890.                     buf[i -= 3] = '\0';
  891.                 }
  892.                 put_str(hex_expand_to(buf, 3));
  893.             } else {
  894.                 hex_display = !hex_display;
  895.             }
  896.         }
  897.         if (!strncmp(&txt[sizeof(txt) - 3], "two", 3))
  898.             crx = 2;
  899.         if (!strncmp(&txt[sizeof(txt) - 3], "one", 3))
  900.             crx = 1;
  901.         if (!strncmp(&txt[sizeof(txt) - 3], "all", 3))
  902.             crx = 0;
  903.     }
  904.     scan_mode = save_scan_mode;
  905.     put_crlf();
  906.     tty_set();
  907.     if (crx) {
  908.         ptextln("End of status report test.");
  909.     } else {
  910.         ptextln("End of echo test.");
  911.     }
  912. }
  913.